// components/waterfall/index.js
Component({
  options: {
    addGlobalClass: true,
  },
  externalClasses: ['my-class'],
  /**
   * 组件的属性列表
   */
  properties: {
    intervalWidth: {
      type: String,
      value: "20rpx"
    }
  },

  /**
   * 组件的初始数据
   */
  data: {
    columnNodes: [],
    stopLoad: false,
    items: []
  },

  /**
   * 组件的方法列表
   */
  methods: {
    /**
     * 批量添加元素
     * 
     * @param {Array} items - 新增的元素数组 
     */
    append(items) {
      if (Object.prototype.toString.call(items) !== '[object Array]') {
        console.error("[masonry]参数类型错误，渲染失败");
        return false;
      }

      this.setData({
        stopLoad: false
      })

      return this._refresh(items);
    },
    /**
     * 批量删除瀑布流中的元素
     * 
     * @param {Number} start - 开始下标 
     * @param {Number} end  - 结束下标
     */
    delete(start, end) {
      const { items } = this.data;
      if (start <= end) {
        let len = end - start;
        let newItems = items.splice(start, len);
        //this._refresh(newItems)
        this.setData({
          items:items
        })
      } else {
        console.error("[masonry]初始下标异常，删除失败！");
      }
    },
    /**
     * 更新数组中的某个元素
     * 
     * @param {Object} newItem  - 修改后的元素
     * @param {Number} index - 需要更新的数组下标
     */
    updateItem(newItem, index) {
      const { items } = this.data;
      if (index <= items.length - 1) {
        this.setData({
          items: [
            ...items.slice(0, index),
            Object.assign(items[index], newItem),
            ...items.slice(index + 1)
          ]
        })
      } else {
        console.error("[masonry]下标越界，修改失败！");
      }
    },
    /**
     * 删除瀑布流中的某个元素
     * 
     * @param {Number} index - 数组下标
     */
    deleteItem(index) {
      const { items } = this.data;
      if (index <= items.length - 1) {
        let newItems = items.splice(index, 1);
        this._refresh(newItems)
      } else {
        console.error("[masonry]下标越界，删除失败！");
      }
    },
    start(items) {
      if (Object.prototype.toString.call(items) !== '[object Array]') {
        console.error("[masonry]参数类型错误，渲染失败");
        return false;
      }

      this.setData({
        items: [],
        stopLoad: false
      })

      return this._refresh(items);
    },
    _render(items, i, onComplete) {
      if (items.length > i && !this.data.stopLoad) {
        this.columnNodes.boundingClientRect().exec(arr => {
          const item = items[i]
          const rects = arr[0]
          const leftColHeight = rects[0].height
          const rightColHeight = rects[1].height

          this.setData({
            items: [...this.data.items, {
              ...item,
              customPosition: leftColHeight <= rightColHeight ? '0' : '1'
            }]
          }, () => {
            this._render(items, ++i, onComplete)
          })
        })
      } else {
        onComplete && onComplete()
      }
    },
    _refresh(items) {
      const query = wx.createSelectorQuery().in(this);
      this.columnNodes = query.selectAll('#dt-left-col,#dt-right-col');
      return new Promise((resolve, reject) => {
        this._render(items, 0, () => {
          resolve()
        })
      }).catch(err => {
        console.log(err);
      })
    },
    /**
     * 停止渲染瀑布流
     */
    stop() {
      this.setData({
        stopLoad: true,
        items: []
      })
    },
  }
})